﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using TrenchcoatRobots.Datatypes;
using TrenchcoatRobots.Datatypes.Input;
using TrenchcoatRobots.Datatypes.States;
using TrenchcoatRobots.Classes.ComponentClasses.Colliders;
using TrenchcoatRobots.Classes.ComponentClasses.UI;

namespace TrenchcoatRobots.Classes.ComponentClasses {
	public enum FacingDirection { Left, Right }
    public enum PlayerNumber { First, Second }
	/// <summary>
	/// Player control is a 2D platformer style controller, with stats & states
	/// </summary>
	class PlayerControl : Component //WORK IN MOTHERFUCKING PROGRESS
	{
		#region Properties
		public bool Grounded { get; protected set; }
		public Vector2 Velocity { get; set; }
		public float MovementSpeed { get; set; }
		public float AirControlModifier { get; set; }
		public float Friction { get; set; }
		public float Drag { get; set; }
		public FacingDirection Direction { get; set; }
		public int Health { get; protected set; }
		public int CurrentHealth { get; protected set; }
		public int JumpStrength { get; set; }
        public PlayerNumber Player { get; set; }
        
        public GameObject teffect;

		protected Vector2 AddVelocity { get; set; }
		protected float jumpCooldown = 1f;
		protected float currentJumpCooldown = 0f;

		#endregion

		#region Constructors
		public PlayerControl(ParentMethod gameObjectMethod, float speed, float airControlModifier, float friction, float drag, int health, PlayerNumber pl)
			: base(gameObjectMethod, "PlayerControl", true) {
			MovementSpeed = speed;
			AirControlModifier = airControlModifier;
			Friction = friction;
			Health = health;
			Drag = drag;
			CurrentHealth = Health;
			Direction = FacingDirection.Right;
			JumpStrength = 300;
            Player = pl;
		}
		#endregion

		#region Methods
		public override void Collided(GameObject otherCopy, CollisionInfo collisionInformation) {
			if (otherCopy.Tags.Contains("ground")) {
				Grounded = true;
				Velocity = new Vector2(Velocity.X, 0);


			}
		}
		public override void Update(ref GameTime gameTime) {
			currentJumpCooldown -= (float)gameTime.ElapsedGameTime.TotalSeconds;

			AddVelocity = new Vector2(); //reset AddVelocity

            List<GameInput> playerInput;

            //Determine the list to use for input
            if (Player == PlayerNumber.First)
                playerInput = GameState.FirstPlayerInputs;
            else
                playerInput = GameState.SecondPlayerInputs;

			for (int i = 0; i < playerInput.Count; i++) {
                if (playerInput[i].Name == "horizontal" && playerInput[i].Value != 0) {
					if (Grounded)
                        AddVelocity += new Vector2(playerInput[i].Value * MovementSpeed, 0);
					else
                        AddVelocity += new Vector2(playerInput[i].Value * MovementSpeed * AirControlModifier, 0);

                    if (GameState.FirstPlayerInputs[i].Value > 0)
                    {
                        Direction = FacingDirection.Right;
                    }
                    else
                    {
                        Direction = FacingDirection.Left;
                    }
				}
				if (GameState.FirstPlayerInputs[i].Name == "jump" && GameState.FirstPlayerInputs[i].Value != 0) {
					Jump();
				}
			}
			if (!Grounded)
				AddVelocity += PhysicsState.Gravity;

			Velocity += AddVelocity;

			if (Grounded) {
				Velocity *= new Vector2(Friction, 1);
			}
			else {
				Velocity *= new Vector2(Drag, 1);
			}

			Velocity = new Vector2(MathHelper.Clamp(Velocity.X, -MovementSpeed, MovementSpeed), Velocity.Y);


			Parent().Position += new Vector2(Velocity.X, Velocity.Y) * (float)gameTime.ElapsedGameTime.TotalSeconds; //Move gameObject

			Parent().Position = new Vector2(MathHelper.Clamp(Parent().Position.X, 0, (ClientSettings.ScreenWidth / 2) - (Parent().GetComponent<BoxCollider>() as BoxCollider).Size.X),
											Parent().Position.Y); //Make sure player doesn't fall off map.

			#region animation
			AnimatedTextureRenderer anim = (Parent().GetComponent<AnimatedTextureRenderer>() as AnimatedTextureRenderer);

			if (anim != null)
				anim.Playing = true;

			if (anim != null) {

                if (Direction == FacingDirection.Left)
                    anim.FlipHorizontal = true;
                else
                    anim.FlipHorizontal = false;

				if (!Grounded) {
					if (Velocity.Y < 0) {
						//play jumping animation
                        if (anim.CurrentAnimationName != "jump") {
                            anim.CurrentAnimationName = "jump";
                        }
					}
					//else {
					//    //play falling animation
					//    if (anim.CurrentAnimationName != "fall") {
					//        anim.CurrentAnimationName = "fall";
					//    }
					//}
				}
				
				else {
					if (Velocity.X != 0) {
						//play walking
						if (anim.CurrentAnimationName != "walk") {
							anim.CurrentAnimationName = "walk";
						}
					}
					else {
						//play idle
						if (anim.CurrentAnimationName != "idle") {
							anim.CurrentAnimationName = "idle";
						}
					}
				}
			}
			#endregion
		}
        
        void Jump() {
			if (Grounded && currentJumpCooldown <= 0.0f) {
				currentJumpCooldown = jumpCooldown;
				AddVelocity = new Vector2(AddVelocity.X, -JumpStrength);
				Grounded = false;
				((TextEffect)teffect.GetComponent<TextEffect>()).Activate(2, 1, "Critical Jump!");
			}
		}

		public void DamagePlayer(int damage) {
			CurrentHealth -= damage;
			CheckHealth();
		}

		public void CheckHealth() {
			if (CurrentHealth <= 0)
				Die();
		}

		public void Die() {
			CurrentHealth = 0;

			// TODOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO: KIL DA PLAIER
		}
		#endregion
	}
}
